"""
@author: 江同学呀
@file: base_document.py
@date: 2024/11/20 20:48
@desc: 
"""


from typing import Dict, Union, Set, List, Tuple, Any, Optional, Generator

from espc.orm.model.base.base import _Base
from espc.orm.model.mapping.field.base_field.base_field import _BaseField


class BaseDocument(_Base):
    """
    ES文档模型基类

    """
    __fields: Optional[List[_BaseField]] = None

    id: str = None

    def __new__(cls, *args, **kwargs):
        __new: BaseDocument = super().__new__(cls)
        return __new

    def __init__(self, **kwargs):
        super().__init__()
        self.__dict__.update(**kwargs)
        return

    def __init_subclass__(cls, **kwargs):
        """
        子类被声明完时调用
        :param kwargs:
        :return:
        """
        if not cls.__fields:
            cls.__fields = [
                field._init_field_name_and_field_name_path(field_name=_a)
                for _a in cls._get_custom_attrs(cls)
                if isinstance(field := getattr(cls, _a), _BaseField)
            ]
        return

    def __repr__(self):
        obj_attr_set: Set = set(self.__class__._get_custom_attrs(self.__class__))
        field_name_list: List[str] = sorted(obj_attr_set.difference(BaseDocument._get_custom_attrs(BaseDocument)))
        # 获取文档模型的字段属性的键值对字符串
        params: str = ', '.join(
            (
                    field_name + "=" +
                    (value[:20] if (value := str(getattr(self, field_name))) and len(value) > 10 else value)
            )
            for field_name in field_name_list if isinstance(getattr(self.__class__, field_name), _BaseField)
        )
        return f"<{self.__class__.__name__} {params} object at {id(self)}>"

    def __iter__(self) -> Generator[Tuple[str, Any], None, None]:
        for field in self.__fields:
            yield field, getattr(self, field)
        return

    @classmethod
    def _build(cls):
        """
        构建索引结构体
        :return:
        """
        _body: Dict = {}
        for field in cls.__fields:
            if isinstance(field, _BaseField):
                _body[field.field_name] = field._build()
        return _body

    def serialize(self) -> Dict:
        """
        序列化文档模型
        :return:
        """
        _body: Dict = {}
        for field in self.__fields:
            if isinstance(field, _BaseField):
                _body[field.field_name] = field.value
        return _body

